package com.wolfsea.launcherdemo
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View

class ProgressRect @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null) : View(context,attributeSet) {

    /*
    * PorterDuff作用场景:在原有图像上绘制其他内容

      PorterDuff.Mode为枚举类,一共有16个枚举值:
      1.PorterDuff.Mode.CLEAR
      所绘制不会提交到画布上。
      *
      2.PorterDuff.Mode.SRC
      显示上层绘制图片
      *
      3.PorterDuff.Mode.DST
      显示下层绘制图片
      *
      4.PorterDuff.Mode.SRC_OVER
      正常绘制显示，上下层绘制叠盖。
      *
      5.PorterDuff.Mode.DST_OVER
      上下层都显示。下层居上显示。
      *
      6.PorterDuff.Mode.SRC_IN
      取两层绘制交集。显示上层。
      *
      7.PorterDuff.Mode.DST_IN
      取两层绘制交集。显示下层。
      *
      8.PorterDuff.Mode.SRC_OUT
      取上层绘制非交集部分。
      *
      9.PorterDuff.Mode.DST_OUT
      取下层绘制非交集部分。
      *
      10.PorterDuff.Mode.SRC_ATOP
      取下层非交集部分与上层交集部分
      *
      11.PorterDuff.Mode.DST_ATOP
      取上层非交集部分与下层交集部分
      *
      12.PorterDuff.Mode.XOR
      异或：去除两图层交集部分
      *
      13.PorterDuff.Mode.DARKEN
      取两图层全部区域，交集部分颜色加深
      *
      14.PorterDuff.Mode.LIGHTEN
      取两图层全部，点亮交集部分颜色
      *
      15.PorterDuff.Mode.MULTIPLY
      取两图层交集部分叠加后颜色
      *
      16.PorterDuff.Mode.SCREEN
      取两图层全部区域，交集部分变为透明色
    * */

    private val defaultWidth = context.resources.getDimension(R.dimen.dp_120).toInt()
    private val defaultHeight = context.resources.getDimension(R.dimen.dp_60).toInt()
    private val rectRound = context.resources.getDimension(R.dimen.dp_10)

    private var currentProgress = 0F

    private var downX = 0F
    private var downY = 0F

    private val originPaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            color = context.resources.getColor(R.color.color_B128C9)
        }
    }

    private val progressPaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            color = context.resources.getColor(R.color.color_fa8989)
            xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        }
    }

    private val originRectF by lazy {
        RectF()
    }

    private val roundProgressRectF by lazy {
        RectF()
    }

    private var mBitmap: Bitmap? = null
    private var mCanvas: Canvas? = null

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val mWidth = when (MeasureSpec.getMode(widthMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(widthMeasureSpec)
            }
            else -> {
                defaultWidth
            }
        } - paddingStart - paddingEnd

        val mHeight = when (MeasureSpec.getMode(heightMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(heightMeasureSpec)
            }
            else -> {
                defaultHeight
            }
        } - paddingTop - paddingBottom

        setMeasuredDimension(mWidth, mHeight)

        originRectF.set(
            0F,
            0F,
            mWidth.toFloat(),
            mHeight.toFloat()
        )
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?.apply {
            //绘制原始图像
            if (mBitmap == null) {
                mBitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888)
            }
            if (mCanvas == null) {
                mBitmap?.let {
                    mCanvas = Canvas(it)
                }
            }
            drawBitmap(mBitmap!!, 0F, 0F, null)

            //绘制进度条
            mCanvas?.apply {
                drawRoundRect(originRectF, rectRound, rectRound, originPaint)
                roundProgressRectF.set(
                    0F,
                    0F,
                    currentProgress,
                    measuredHeight.toFloat()
                )
                drawRect(roundProgressRectF, progressPaint)
            }
        }
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        performClick()
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d(TAG, "MotionEvent.ACTION_DOWN")
                downX = event.x
                downY = event.y
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d(TAG, "MotionEvent.ACTION_MOVE")
                val moveX = event.x
                val moveY = event.y
                val diffX = moveX - downX
                if (Math.abs(moveX - downX) > Math.abs(moveY - downY)) {
                    currentProgress += diffX
                    currentProgress = Math.min(currentProgress, measuredWidth.toFloat())
                    invalidate()
                }
                downX = moveX
                downY = moveY
            }
        }
        return true
    }

    override fun performClick(): Boolean {
        return super.performClick()
    }

    companion object {
        const val TAG = "ProgressRect"
    }

}